package vnreal.map;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.event.MouseInputListener;

import org.jdesktop.swingx.JXMapKit;
import org.jdesktop.swingx.JXMapViewer;
import org.jdesktop.swingx.input.CenterMapListener;
import org.jdesktop.swingx.input.ContextMenu;
import org.jdesktop.swingx.input.NewNodeMapListener;
import org.jdesktop.swingx.input.PanKeyListener;
import org.jdesktop.swingx.input.PanMouseInputListener;
import org.jdesktop.swingx.input.ZoomMouseWheelListenerCenter;
import org.jdesktop.swingx.mapviewer.DefaultTileFactory;
import org.jdesktop.swingx.mapviewer.GeoPosition;
import org.jdesktop.swingx.mapviewer.LocalResponseCache;
import org.jdesktop.swingx.mapviewer.TileFactoryInfo;
import org.jdesktop.swingx.mapviewer.WaypointPainter;
import org.jdesktop.swingx.painter.CompoundPainter;
import org.jdesktop.swingx.painter.LinkPainter;
import org.jdesktop.swingx.painter.Painter;
import org.jdesktop.swingx.VirtualEarthTileFactoryInfo;

import vnreal.ZNEW.XmlTest;
import vnreal.ZNEW.GraphTest.Node;
import vnreal.ZNEW.GraphTest.SubstrateLink;
import vnreal.ZNEW.GraphTest.WorkOnPaths;
import vnreal.ZNEW.Xml.SLink;
import vnreal.ZNEW.Xml.SNode;
import vnreal.ZNEW.Xml.VLink;
import vnreal.ZNEW.Xml.VNetwork;
import vnreal.ZNEW.Xml.VNode;

public class Map {
	public static JXMapKit mapKit = new JXMapKit();
	public static Set<MyWaypoint> waypoints = new HashSet<MyWaypoint>();
	public static CompoundPainter<JXMapViewer> cp = new CompoundPainter<JXMapViewer>();
	public static WaypointPainter<MyWaypoint> waypointPainter = new WaypointPainter<MyWaypoint>();
	public static int numberOfElements = -1;
	public static boolean isSubstrateNodesExists;
	public static boolean isSubstrateLinksExists;
	public static boolean isVirtualNetworksExists;

	/*
	 * private static void isNullObjectsExists() { isSubstrateNetworkExists =
	 * true; isVirtualNetworksExists = true;
	 * 
	 * if(XmlTest.scenario.getSubstrateNetwork() == null) {
	 * isSubstrateNetworkExists = false; isVirtualNetworksExists = false;
	 * return; } if(XmlTest.scenario.getVirtualNetworks() == null) {
	 * isVirtualNetworksExists = false; return; } }
	 */
	private static void isSNodesExists() {
		isSubstrateNodesExists = true;
		if (XmlTest.scenario.getSubstrateNetwork().getNodes().getNode() == null) {
			isSubstrateNodesExists = false;
		}
	}

	private static void isSLinksExists() {
		isSubstrateLinksExists = true;
		if (XmlTest.scenario.getSubstrateNetwork().getLinks().getLink() == null) {
			isSubstrateLinksExists = false;
		}
	}

	private static void isVNetworksExists() {
		isVirtualNetworksExists = true;
		if (XmlTest.scenario.getVirtualNetworks().getVirtualNetwork() == null) {
			
			isVirtualNetworksExists = false;
		}
	}
	public static void doPreCheck() {
		isSNodesExists();
		isSLinksExists();
		isVNetworksExists();
	}
	public static void showMap() {
		setupJXMapViewer();
		// / tu mamy scenario gotowy

		doPreCheck();
		
		
		if (isSubstrateNodesExists) {
			WorkOnPaths.getNodes();
			countSubstrateNodesObjects();
		}
		if (isSubstrateLinksExists) {
			WorkOnPaths.getLinks();
			countSubstrateLinksObjects();
		}
		if (isVirtualNetworksExists) {
			countVirtualNodesObjects();
			countVirtualLinksObjects();
		}
		drawAll();

	}

	private static Set<MyWaypoint> createWaypoints() {
		Set<MyWaypoint> waypoints = new HashSet<MyWaypoint>();
		for (Node node : WorkOnPaths.substrateNodes) {
			GeoPosition position = new GeoPosition(node.latitude, node.longitude);
			MyWaypoint waypoint = new MyWaypoint(node.globalNodeId, Color.WHITE, position);
			waypoints.add(waypoint);
		}
		return waypoints;
	}

	public static void drawAll() {
		Painter<JXMapViewer> drawLinks = new LinkPainter<JXMapViewer>();
		waypoints.clear();
		waypoints.addAll(createWaypoints());
		waypointPainter.setWaypoints(waypoints);
		waypointPainter.setRenderer(new FancyWaypointRenderer());

		cp.setPainters(drawLinks, waypointPainter);
		cp.setCacheable(false);
		mapKit.getMainMap().setOverlayPainter(cp);
	}

	private static void setupJXMapViewer() {
		// Create a TileFactoryInfo for Virtual Earth
		TileFactoryInfo info = new VirtualEarthTileFactoryInfo(VirtualEarthTileFactoryInfo.MAP);
		DefaultTileFactory tileFactory = new DefaultTileFactory(info);
		tileFactory.setThreadPoolSize(8);

		// Setup local file cache
		File cacheDir = new File(System.getProperty("user.home") + File.separator + ".jxmapviewer2");
		LocalResponseCache.installResponseCache(info.getBaseURL(), cacheDir, false);

		mapKit.setTileFactory(tileFactory);
		mapKit.getMainMap().setZoom(2);
		mapKit.setAddressLocation(new GeoPosition(53.75, .0));
		MouseInputListener mia = new PanMouseInputListener(mapKit.getMainMap());
		mapKit.addMouseListener(mia);
		mapKit.addMouseMotionListener(mia);
		mapKit.addMouseListener(new CenterMapListener(mapKit.getMainMap()));
		mapKit.addMouseWheelListener(new ZoomMouseWheelListenerCenter(mapKit.getMainMap()));
		mapKit.addKeyListener(new PanKeyListener(mapKit.getMainMap()));
		mapKit.addMouseListener(new ContextMenu(mapKit.getMainMap()));
	}

	private static void countSubstrateNodesObjects() {
		for (SNode item : XmlTest.scenario.getSubstrateNetwork().getNodes().getNode()) {
			System.out.println("XmlTest.scenario.getSubstrateNetwork().getNodes().getNode():   " + item.getId());
			if (Integer.valueOf(item.getId()) > numberOfElements) {
				System.out.println("Integer.valueOf(item.getId()) > numberOfElements     " + item.getId());
				numberOfElements = Integer.valueOf(item.getId());
			}
		}
	}

	private static void countSubstrateLinksObjects() {
		for (SLink item : XmlTest.scenario.getSubstrateNetwork().getLinks().getLink()) {
			if (Integer.valueOf(item.getId()) > numberOfElements) {
				numberOfElements = Integer.valueOf(item.getId());
			}
		}
	}

	private static void countVirtualNodesObjects() {
		for (VNetwork net : XmlTest.scenario.getVirtualNetworks().getVirtualNetwork()) {
			if(net.getNodes().getNode() != null) {
				for (VNode item : net.getNodes().getNode()) {
					if (Integer.valueOf(item.getId()) > numberOfElements) {
						numberOfElements = Integer.valueOf(item.getId());
					}
				}
			}
		}
	}

	private static void countVirtualLinksObjects() {
		for (VNetwork net : XmlTest.scenario.getVirtualNetworks().getVirtualNetwork()) {
			if(net.getLinks().getLink() != null) {
				for (VLink item : net.getLinks().getLink()) {
					if (Integer.valueOf(item.getId()) > numberOfElements) {
						numberOfElements = Integer.valueOf(item.getId());
					}
				}
			}
		}
	}
}
